package top.lywivan.stack;

import java.util.Arrays;

/**
 * @author :lyw.ivan
 * @date :Created in 2022/6/3
 * @description :
 * @version: 1.0
 */
public class Stack<E> {

    //定义数组
    private Object[] elementData;

    //定义栈中的元素
    private int elementCount;

    public Stack(int capacity) {
        elementData=new Object[capacity];
    }

    public Stack(){
        this(10);
    }

    /**
     * 返回栈中元素个数
     * @return
     */
    public int size() {
        return elementCount;
    }
    /**
     * 判断栈是否为空
     * @return
     */
    public boolean empty() {
        return elementCount==0;
    }
    /**
     * 将元素压入栈
     * @param item 被存入栈的元素
     * @return
     */
    public E push(E item) {
        //确保容量足够
        ensureCapacity(elementCount+1);
        //向最后添加元素
        elementData[elementCount]=item;
        elementCount++;
        return item;
    }

    private void ensureCapacity(int newCapacity) {
        if(newCapacity>elementData.length){
            grow(newCapacity);
        }
    }

    private void grow(int targetCapacity) {
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity+oldCapacity>>1;
        if(newCapacity<targetCapacity){
            newCapacity=targetCapacity;
        }
        elementData = Arrays.copyOf(elementData,newCapacity);
    }

    /**
     * 获取栈顶元素，但并不移除，如果栈空则返回null
     * @return
     */
    public E peek() {
        if(empty()){
            return null;
        }
        return indexOf(elementCount-1);
    }

    private E indexOf(int index) {
        if(index<0||index>=elementCount){
            throw new IllegalArgumentException("illegal argument,index="+index);
        }
        return (E) elementData[index];
    }

    /**
     * 移除栈顶元素并返回，如果栈为空则返回null
     * @return
     */
    public E pop() {
        E peek = peek();
        removeElementByIndex(elementCount-1);
        return peek;
    }

    private void removeElementByIndex(int index) {
        if(index<0||index>=elementCount){
            throw new IllegalArgumentException("illegal argument,index="+index);
        }
        if(index<elementCount-1){
            System.arraycopy(elementData,index+1,elementData,index,elementCount-index-1);
        }
        elementCount--;
        elementData[elementCount]=null;
    }

    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder("[");
        for (int i = 0; i < elementCount; i++) {
            sb.append(elementData[i]).append(",");
        }
        return sb.append("]").toString();
    }
}
